package service

import (
	"fmt"
	"sen-golang-study/go_game_study/hero_story_go_server/game_server/internal/domain/user/entity"
	"sen-golang-study/go_game_study/hero_story_go_server/game_server/internal/domain/user/service"
	"sen-golang-study/go_game_study/hero_story_go_server/game_server/internal/infrastructure/async"
	"time"
)

// UserLoginService 用户登录应用服务
type UserLoginService struct {
	userDomainService *service.UserDomainService
}

// NewUserLoginService 创建用户登录应用服务
func NewUserLoginService(userDomainService *service.UserDomainService) *UserLoginService {
	return &UserLoginService{
		userDomainService: userDomainService,
	}
}

// LoginByPasswordAsync 异步密码登录
func (s *UserLoginService) LoginByPasswordAsync(username, password string, complete func(result *async.AsyncResult)) {
	go func() {
		result := &async.AsyncResult{}

		// 执行登录逻辑
		user, err := s.loginByPassword(username, password)
		if err != nil {
			result.SetError(err)
		} else {
			// 构造登录结果
			loginResult := map[string]interface{}{
				"user_id":     user.GetUserID(),
				"username":    user.GetUserName(),
				"hero_avatar": user.GetHeroAvatar(),
			}
			result.SetReturnValue(loginResult)
		}

		// 调用完成回调
		result.SetReturnObj(complete)
		result.DoComplete()
	}()
}

// loginByPassword 密码登录内部实现
func (s *UserLoginService) loginByPassword(username, password string) (*entity.User, error) {
	if len(username) == 0 {
		return nil, fmt.Errorf("username cannot be empty")
	}
	if len(password) == 0 {
		return nil, fmt.Errorf("password cannot be empty")
	}

	// 尝试获取用户
	user, err := s.userDomainService.GetUserByName(username)
	if err != nil {
		return nil, fmt.Errorf("failed to get user: %w", err)
	}

	if user == nil {
		// 用户不存在，创建新用户
		return nil, fmt.Errorf("user not found")
	} else {
		// 用户存在，验证密码
		if user.GetPassword() != password {
			return nil, fmt.Errorf("invalid password")
		}

		// 更新最后登录时间
		user.UpdateLastLoginTime(time.Now().Unix())

		// 保存用户数据
		err = s.userDomainService.SaveUser(user)
		if err != nil {
			return nil, fmt.Errorf("failed to update user: %w", err)
		}
	}

	return user, nil
}
